/** 
 ** Copyright (c) 2010 Ushahidi Inc
 ** All rights reserved
 ** Contact: team@ushahidi.com
 ** Website: http://www.ushahidi.com
 ** 
 ** GNU Lesser General Public License Usage
 ** This file may be used under the terms of the GNU Lesser
 ** General Public License version 3 as published by the Free Software
 ** Foundation and appearing in the file LICENSE.LGPL included in the
 ** packaging of this file. Please review the following information to
 ** ensure the GNU Lesser General Public License version 3 requirements
 ** will be met: http://www.gnu.org/licenses/lgpl.html. 
 ** 
 **
 ** If you have questions regarding the use of this file, please contact
 ** Ushahidi developers at team@ushahidi.com.
 ** 
 **/

package com.ushahidi.android.app;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Set;
import java.util.Vector;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
import com.ushahidi.android.app.IProvide.OneTimeDeviceLocationListener;
import com.ushahidi.android.app.data.AddIncidentData;
import com.ushahidi.android.app.data.UshahidiDatabase;
import com.ushahidi.android.app.net.UshahidiHttpClient;
import com.ushahidi.android.app.util.Util;

public class AddIncident extends DashboardActivity
{

    /**
     * category that exists on the phone before any connection to a server, at
     * present it is trusted reporter, id number 4 but will change to specific
     * 'uncategorized' category when it is ready on the server
     */
    private static final String       UNCATEGORIZED_CATEGORY_ID    = "4";

    private static final String       UNCATEGORIZED_CATEGORY_TITLE = "uncategorized";

    private static final int          HOME                         = Menu.FIRST + 1;

    private static final int          LIST_INCIDENT                = Menu.FIRST + 2;

    private static final int          INCIDENT_MAP                 = Menu.FIRST + 3;

    private static final int          INCIDENT_REFRESH             = Menu.FIRST + 4;

    private static final int          SETTINGS                     = Menu.FIRST + 5;

    private static final int          ABOUT                        = Menu.FIRST + 6;

    private static final int          GOTOHOME                     = 0;

    private static final int          MAP_INCIDENTS                = 1;

    private static final int          LIST_INCIDENTS               = 2;

    private static final int          REQUEST_CODE_SETTINGS        = 2;

    private static final int          REQUEST_CODE_ABOUT           = 3;

    private static final int          REQUEST_CODE_IMAGE           = 4;

    private static final int          REQUEST_CODE_CAMERA          = 5;

    private static final int          REQUEST_CODE_CHANGE_LOC      = 6;

    private static final int          VIEW_MAP                     = 1;

    private static final int          VIEW_SEARCH                  = 2;

    private Geocoder                  mGc;

    private List<Address>             mFoundAddresses;

    // date and time
    private int                       mYear;

    private int                       mMonth;

    private int                       mDay;

    private int                       mHour;

    private int                       mMinute;

    private int                       mCounter                     = 0;

    private static double             sLongitude = 0.0;

    private static double             sLatitude = 0.0;
    
    private static double 			  currentLongitude = 0.0;
    
    private static double			  currentLatitude = 0.0 ;
    
    private boolean 				  locDeterminedFlag=false;
    
    private boolean          refreshState          = false;
    
    private String 					  sLocationName="Current Location";
    
    private String 					  sCurrLocation="Current Location";
        
    private String                    mErrorMessage                = "";

    private String                    mDateToSubmit                = "";

    private String                    mFilename                    = "";

    private boolean                   mError                       = false;

    private EditText                  mIncidentTitle;

    private EditText                  mIncidentLocation;

    private EditText                  mIncidentDesc;

    private TextView                  mIncidentDate;

    private ImageView                 mSelectedPhoto;

    private TextView                  mSelectedCategories;
    

    // private TextView mReportLocation;

    private TextView                  activityTitle;

    private Button                    mBtnSend;

    private Button                    change_loc;

    private Button                    mBtnCancel;

    private Button                    mBtnAddCategory;

    private Button                    mPickTime;

    private Button                    mPickDate;

    private Button                    mBtnPicture;

    private HashMap<Integer, Integer> mTimeDigits;

    private Bundle                    mBundle;

    private Bundle                    mExtras;

    // private MapView mapView = null;

    // private MapController mapController;
    private static final int 		  THUMBNAIL_SIZE=300;

    private static final int          DIALOG_ERROR_NETWORK         = 0;

    private static final int          DIALOG_ERROR_SAVING          = 1;

    private static final int          DIALOG_CHOOSE_IMAGE_METHOD   = 2;

    private static final int          DIALOG_MULTIPLE_CATEGORY     = 3;

    private static final int          TIME_DIALOG_ID               = 4;

    private static final int          DATE_DIALOG_ID               = 5;

    private final static Handler      mHandler                     = new Handler();

    private Vector<String>            mVectorCategories            = new Vector<String>();

    private Vector<String>            mCategoriesId                = new Vector<String>();

    private HashMap<String, String>   mCategoriesTitle             = new HashMap<String, String>();

    private HashMap<String, String>   mParams                      = new HashMap<String, String>();

    private Spinner                   sp_fatalities;

    private Spinner                   sp_injured;

    private Spinner                   sp_property_damage;

    private ArrayList<String>         list_fatalities              = new ArrayList<String>();

    private ArrayList<String>         list_injured                 = new ArrayList<String>();

    // private ArrayList<String> list_property_damage =new ArrayList<String>();

    private ArrayAdapter<String>      adapter_fatalities;

    private ArrayAdapter<String>      adapter_injured;

    private ArrayAdapter<String>      adapter_property_damage;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
	super.onCreate(savedInstanceState);
	requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
	setContentView(R.layout.add_incident);
	
	// //////////yujie chen: add spinner to
	// fatalities/////////////////////////////
	/*
	 * this.sp_fatalities=(Spinner)findViewById(R.id.incident_fatalities_sp);
	 * String [] ls_fata_option=getResources().getStringArray(R.array.
	 * incident_fatalities_options); for(int
	 * i=0;i<ls_fata_option.length;++i) {
	 * this.list_fatalities.add(ls_fata_option[i]); } //把数组导入到ArrayList中
	 * 
	 * 
	 * adapter_fatalities=new
	 * ArrayAdapter<String>(this,android.R.layout.simple_spinner_item
	 * ,list_fatalities);
	 * adapter_fatalities.setDropDownViewResource(android.
	 * R.layout.simple_spinner_dropdown_item); //设置下拉菜单的风格
	 * sp_fatalities.setAdapter(adapter_fatalities); //绑定适配器
	 * sp_fatalities.setPrompt("fatalities"); //设置对话框标题栏
	 */

	// /////////yujie chen:add spinner to
	// fatalities///////////////////////////////

	// //////////yujie chen: add spinner to
	// injured/////////////////////////////
	/*
	 * this.sp_injured=(Spinner)findViewById(R.id.incident_injured_sp);
	 * 
	 * String [] ls_injured_option=getResources().getStringArray(R.array.
	 * incident_injured_options); for(int
	 * i=0;i<ls_injured_option.length;++i) {
	 * this.list_injured.add(ls_injured_option[i]); } //把数组导入到ArrayList中
	 * adapter_injured=new
	 * ArrayAdapter<String>(this,android.R.layout.simple_spinner_item
	 * ,list_injured);
	 * adapter_injured.setDropDownViewResource(android.R.layout
	 * .simple_spinner_dropdown_item); //设置下拉菜单的风格
	 * sp_injured.setAdapter(adapter_injured); //绑定适配器
	 * sp_injured.setPrompt("Injured"); //设置对话框标题栏
	 */

	// /////////yujie chen:add spinner to
	// injured///////////////////////////////

	// //////////yujie chen: add spinner to
	// property_damage/////////////////////////////
	/*
	 * this.sp_property_damage=(Spinner)findViewById(R.id.
	 * incident_property_damage_sp); String []
	 * ls_property_damage_option=getResources
	 * ().getStringArray(R.array.incident_property_damage_options); for(int
	 * i=0;i<ls_property_damage_option.length;++i) {
	 * this.list_property_damage.add(ls_property_damage_option[i]); }
	 * //把数组导入到ArrayList中 adapter_property_damage=new
	 * ArrayAdapter<String>(this
	 * ,android.R.layout.simple_spinner_item,list_property_damage);
	 * adapter_property_damage
	 * .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item
	 * ); //设置下拉菜单的风格
	 * sp_property_damage.setAdapter(adapter_property_damage); //绑定适配器
	 * sp_property_damage.setPrompt("Property Damage"); //设置对话框标题栏
	 */

	// /////////yujie chen:add spinner to
	// injured///////////////////////////////
	mFoundAddresses = new ArrayList<Address>();
	
	mGc = new Geocoder(this, Locale.US);

	// load settings
	UshahidiPref.loadSettings(AddIncident.this);

	// setDeviceLocation();
	initComponents();
    
	readyLocationService();
    }

    @Override
    protected void onDestroy()
    {
	// house keeping
	//((LocationManager) getSystemService(Context.LOCATION_SERVICE))
//        .removeUpdates(new DeviceLocationListener());
	unregisterListeners();
	super.onDestroy();
    }

    /**
     * Any time we are paused we need to save away the current state, so it will
     * be restored correctly when we are resumed.
     */
    @Override
    protected void onPause()
    {
//	((LocationManager) getSystemService(Context.LOCATION_SERVICE))
//	        .removeUpdates(new DeviceLocationListener());
	unregisterListeners();

	SharedPreferences.Editor editor = getPreferences(0).edit();
	editor.putString("title", mIncidentTitle.getText().toString());
	editor.putString("cate",Util.implode(mVectorCategories));
	editor.putString("desc", mIncidentDesc.getText().toString()); //TODO recovery when needed
	editor.putString("location", mIncidentLocation.getText().toString());
	editor.commit();
	super.onPause();
    }
    
    @Override
    protected void onStop()
    {
	super.onStop();
	// house keeping
//	((LocationManager) getSystemService(Context.LOCATION_SERVICE))
//      .removeUpdates(new DeviceLocationListener());
	unregisterListeners();
    }

    /**
     * Upon being resumed we can retrieve the current state. This allows us to
     * update the state if it was changed at any time while paused.
     */
    @Override
    protected void onResume()
    {
//	if (!TextUtils.isEmpty(UshahidiPref.fileName))
//	{
//	    mBtnPicture.setText(getString(R.string.change_photo));
//	}
    showCategories();
	SharedPreferences prefs = getPreferences(0);
	String title = prefs.getString("title", null);
	String desc = prefs.getString("desc", null);
	String category= prefs.getString("cate", null);

	if (title != null)
	    mIncidentTitle.setText(title, TextView.BufferType.EDITABLE);

	if (desc != null)
	    mIncidentDesc.setText(desc, TextView.BufferType.EDITABLE);
	if (category!=null)
		{
			mVectorCategories=new Vector<String> ();
			String []categoryArray =category.split(",");
			for(int i=0;i<categoryArray.length;++i)
			{
				mVectorCategories.add(categoryArray[i]);
			}
			
			mSelectedCategories.setText(
					Util.limitString(
		                    // mCategoriesTitle.get(mVectorCategories.get(0)),
		                    Util.implode(getCategoriesByIds(mVectorCategories)),
		                    15)
							);
		}
	else
		{
			mSelectedCategories.setText("");
		}
	//Request updated location when resume
	registerHighOneTimeListener();
	
	super.onResume();
    }

    
    //=========================
    //= TODO Location Service =
    //=========================
    LocationManager manager;
    long updateTimeMsec = 0;
    float updateDistance = 0;
    LocationProvider high;
    LocationProvider low;
    
    private OneTimeDeviceLocationListener high_listener=null;
    private OneTimeDeviceLocationListener low_listener=null;
    
    private void registerHighOneTimeListener()
    {
	high_listener = new OneTimeDeviceLocationListener();
	manager.requestLocationUpdates(high.getName(), updateTimeMsec, updateDistance,
		high_listener);
    }
    private void registerLowOneTimeListener()
    {
	low_listener = new OneTimeDeviceLocationListener();
	manager.requestLocationUpdates(low.getName(), updateTimeMsec, updateDistance,
		low_listener);
    }
    private void unregisterListeners()
    {
	if(high_listener!=null)
	{
	    manager.removeUpdates(high_listener);
	    high_listener=null;
	}
	if(low_listener!=null)
	{
	    manager.removeUpdates(low_listener);
	    low_listener=null;
	}
    }
    // Fetches the current location of the device.
    // create two different listeners, one for once, one for long
    // temporarily, periodical location service is not needed because
    // we are not following user
    private void readyLocationService()
    {
	//===============================
	//ready one time location request
	//===============================
	//listener = new OneTimeDeviceLocationListener();
    
	manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
	
	// get low and high accuracy provider
	// this is tempararily changed, due to simulation
	//	low = manager.getProvider(manager.getBestProvider(
	//	        Util.createCoarseCriteria(), true));
	//	high = manager.getProvider(manager.getBestProvider(
	//	        Util.createFineCriteria(), true));

	low = manager.getProvider(manager.NETWORK_PROVIDER);
	high = manager.getProvider(manager.GPS_PROVIDER);
	
	//imediately register 2 one time service to update location
	registerHighOneTimeListener();
	registerLowOneTimeListener();
    }

   /* Drawable marker;
    private void configureMap()
    {
	Log.v("Oceanmaster", "Mapview BuiltInZoomControls On");
	
	marker = getResources().getDrawable(R.drawable.marker);
	marker.setBounds(0, 0, marker.getIntrinsicWidth(),
	        marker.getIntrinsicHeight());
		
	mapView.getController().setZoom(16);//changed from 14 to 16
	mapView.setBuiltInZoomControls(true);
	//mapView.displayZoomControls(true);
    }
    
	*/
    /*private void placeMarker(int markerLatitude, int markerLongitude)
    {
	//TODO switch marker icons
	//TODO Can we optimized this by directly change exosting MapMarker. Not sure yet
	mapView.getOverlays().add(
	        new MapMarker(marker, markerLatitude, markerLongitude));
    }
	*/
    public GeoPoint getPoint(double lat, double lon)
    {
	return (new GeoPoint((int) (lat * 1000000.0), (int) (lon * 1000000.0)));
    }

    //Modified by OceanMaster, added updateText argument
   /*
    private void centerLocation(GeoPoint centerGeoPoint, boolean updateText)
    {
	mapController.animateTo(centerGeoPoint);
	sLatitude = centerGeoPoint.getLatitudeE6() / 1.0E6;
	sLongitude = centerGeoPoint.getLongitudeE6() / 1.0E6;
	if(updateText)
	    mIncidentLocation.setText(getLocationFromLatLon(sLatitude, sLongitude));
	placeMarker(centerGeoPoint.getLatitudeE6(), centerGeoPoint.getLongitudeE6());
    }
    */
    /*
    private void setLocationBySearch(String search)
    {
	Log.v("Oceanmaster", "setLocationBySearch : "+search);
	if(search==null || search.length()==0)
	{
	    Util.showToast(IProvide.this,"Please fill search field first to find location");
	    return;
	}
	try
        {
	    List<Address> result = mGc.getFromLocationName(search, 1);
	    if(result.size()<=0)
	    {
		 Util.showToast(IProvide.this,"No result found");
		 return;
	    }
	    
	    Address location = result.get(0);
	    
	    sLatitude = location.getLatitude();
	    sLongitude = location.getLongitude();

            centerLocation(getPoint(sLatitude, sLongitude),false);
	    mReportLocation.setText(String.valueOf(sLatitude) + ", "
		        + String.valueOf(sLongitude));
	    
        }
        catch (IOException e)
        {
            Util.showToast(IProvide.this,
                    "Error occured while trying to search Location");
        }
   }
    */
    //get the real location name from the latitude and longitude.
    public String getLocationFromLatLon(double lat, double lon)
    {
	Log.v("Oceanmaster", "Location name service requested");
	try
	{
		
	    Address address;
	    mFoundAddresses = mGc.getFromLocation(lat, lon, 2);
	    if (mFoundAddresses.size() > 0)
	    {
		address = mFoundAddresses.get(0);
		return address.getSubAdminArea();
	    }
	    else
	    {
		return "";
	    }
	}
	catch (IOException e)
	{
	    e.printStackTrace();
	}
	return "";
    }
    
    /*
    @Override
  protected boolean isRouteDisplayed()
    {
	return false;
    }*/
    
   /* public class MapMarker extends ItemizedOverlay<OverlayItem>
    {

	private List<OverlayItem> locations = new ArrayList<OverlayItem>();

	private Drawable          marker;

	private OverlayItem       myOverlayItem;

	public MapMarker(Drawable defaultMarker, int LatitudeE6, int LongitudeE6)
	{
	    super(defaultMarker);
	    this.marker = defaultMarker;

	    // create locations of interest
	    GeoPoint myPlace = new GeoPoint(LatitudeE6, LongitudeE6);

	    myOverlayItem = new OverlayItem(myPlace, " ", " ");

	    locations.add(myOverlayItem);

	    populate();

	}
	
	//Added by OceanMaster, not tested
	public void addLocation(int LatitudeE6, int LongitudeE6)
	{
	    GeoPoint myPlace = new GeoPoint(LatitudeE6, LongitudeE6);
	    myOverlayItem = new OverlayItem(myPlace, " ", " ");
	    locations.add(myOverlayItem);
	    populate();	    
	}

	@Override
	protected OverlayItem createItem(int i)
	{
	    return locations.get(i);
	}

	@Override
	public int size()
	{
	    return locations.size();
	}

	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow)
	{
	    super.draw(canvas, mapView, shadow);
	    boundCenterBottom(marker);
	}
    }
   */
    // get the current location of the device/user
    public class OneTimeDeviceLocationListener implements LocationListener
    {
	OneTimeDeviceLocationListener()
	{
	    super();
	    Log.v("Oceanmaster","new OneTimeListener Created");
	}
	
	public void onLocationChanged(Location location)
	{
	    Log.v("Oceanmaster", "Location Changed");
	    if (location != null)
	    {
		manager.removeUpdates(OneTimeDeviceLocationListener.this);

		currentLatitude = location.getLatitude();
		currentLongitude = location.getLongitude();
		//sLatitude  = currentLatitude;
		//sLongitude = currentLongitude;
		//sLocationName =  "CurrentLocation";
		if(sLocationName.equals("Current Location") || sLocationName == "")
		{
			sLocationName =  "Current Location";
			mIncidentLocation.setText(sCurrLocation);
			//sLocationName = "Current Location";
		}
		
		//locDeterminedFlag=true;
		
		//Log.v("Oceanmaster",
	             //"current location is:" + "(" +currentLatitude +", "+ currentLongitude+")");
		//centerLocation(getPoint(sLatitude, sLongitude),true);
		//mReportLocation.setText(String.valueOf(sLatitude) + ", "
		  //      + String.valueOf(sLongitude));
	    }
	}

	public void onProviderDisabled(String provider)
	{
	    Util.showToast(AddIncident.this, R.string.location_not_found);
	    Log.v("Oceanmaster", "LocationProvider "+provider.toString()+" Disabled");
	}

	public void onProviderEnabled(String provider)
	{
	    Log.v("Oceanmaster", "LocationProvider "+provider.toString()+" Enabled");
	}

	public void onStatusChanged(String provider, int status, Bundle extras)
	{

	}
    }
    
    
    
    
    // menu stuff
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
	    ContextMenu.ContextMenuInfo menuInfo)
    {
	populateMenu(menu);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
	populateMenu(menu);

	return (super.onCreateOptionsMenu(menu));
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {

	return (applyMenuChoice(item) || super.onOptionsItemSelected(item));
    }

    @Override
    public boolean onContextItemSelected(MenuItem item)
    {

	return (applyMenuChoice(item) || super.onContextItemSelected(item));
    }

    private void populateMenu(Menu menu)
    {
	MenuItem i;

	i = menu.add(Menu.NONE, HOME, Menu.NONE, R.string.menu_home);
	i.setIcon(R.drawable.ushahidi_home);

	i = menu.add(Menu.NONE, LIST_INCIDENT, Menu.NONE,
	        R.string.incident_list);
	i.setIcon(R.drawable.ushahidi_list);

	i = menu.add(Menu.NONE, INCIDENT_MAP, Menu.NONE,
	        R.string.incident_menu_map);
	i.setIcon(R.drawable.ushahidi_map);

	i = menu.add(Menu.NONE, INCIDENT_REFRESH, Menu.NONE,
	        R.string.incident_menu_refresh);
	i.setIcon(R.drawable.ushahidi_refresh);

	i = menu.add(Menu.NONE, SETTINGS, Menu.NONE, R.string.menu_settings);
	i.setIcon(R.drawable.ushahidi_settings);

	i = menu.add(Menu.NONE, ABOUT, Menu.NONE, R.string.menu_about);
	i.setIcon(R.drawable.ushahidi_about);

    }

    private boolean applyMenuChoice(MenuItem item)
    {
	Intent launchPreferencesIntent;
	switch (item.getItemId())
	{

	    case LIST_INCIDENT:
		launchPreferencesIntent = new Intent(AddIncident.this,
				IProvide.class);
		startActivityForResult(launchPreferencesIntent, LIST_INCIDENTS);
		setResult(RESULT_OK);
		return true;

	    case INCIDENT_MAP:
		launchPreferencesIntent = new Intent(AddIncident.this,
		        ViewIncidents.class);
		startActivityForResult(launchPreferencesIntent, MAP_INCIDENTS);
		return true;

	    case HOME:
		launchPreferencesIntent = new Intent(AddIncident.this,
		        Ushahidi.class);
		startActivityForResult(launchPreferencesIntent, GOTOHOME);
		setResult(RESULT_OK);
		return true;

	    case ABOUT:
		launchPreferencesIntent = new Intent(AddIncident.this,
		        About.class);
		startActivityForResult(launchPreferencesIntent,
		        REQUEST_CODE_ABOUT);
		setResult(RESULT_OK);
		return true;

	    case SETTINGS:
		launchPreferencesIntent = new Intent().setClass(
		        AddIncident.this, Settings.class);

		// Make it a subactivity so we know when it returns
		startActivityForResult(launchPreferencesIntent,
		        REQUEST_CODE_SETTINGS);
		return true;

	}
	return false;
    }

    /**
     * Initialize UI components
     */
    private void initComponents()
    {

	mBtnPicture = (Button) findViewById(R.id.btnPicture);
	mBtnAddCategory = (Button) findViewById(R.id.add_category);
	mBtnSend = (Button) findViewById(R.id.incident_add_btn);
	mBtnCancel = (Button) findViewById(R.id.incident_add_cancel);
	// mIncidentDate = (TextView)findViewById(R.id.lbl_date);
	// mPickDate = (Button)findViewById(R.id.pick_date);
	// mPickTime = (Button)findViewById(R.id.pick_time);
	// mReportLocation = (TextView)findViewById(R.id.latlon);
	mSelectedPhoto = (ImageView) findViewById(R.id.sel_photo_prev);
	mSelectedCategories = (TextView) findViewById(R.id.lbl_category);
	activityTitle = (TextView) findViewById(R.id.title_text);
	if (activityTitle != null)
	    activityTitle.setText(getTitle());
	mIncidentTitle = (EditText) findViewById(R.id.incident_title);
	mIncidentLocation = (EditText) findViewById(R.id.incident_location);
	// mapView = (MapView)findViewById(R.id.location_map);
	change_loc = (Button) findViewById(R.id.change_loc);
	// mapController = mapView.getController();
	mIncidentTitle
	        .setOnFocusChangeListener(new View.OnFocusChangeListener()
	        {

		    public void onFocusChange(View v, boolean hasFocus)
		    {
		        if (!hasFocus)
		        {
			    if (TextUtils.isEmpty(mIncidentTitle.getText()))
			    {
			        mIncidentTitle
			                .setError(getString(R.string.empty_report_title));
			    }
		        }

		    }

	        });

	mIncidentLocation
	        .setOnFocusChangeListener(new View.OnFocusChangeListener()
	        {

		    public void onFocusChange(View v, boolean hasFocus)
		    {
		        if (!hasFocus)
		        {
			    if (TextUtils.isEmpty(mIncidentLocation.getText()))
			    {
			        mIncidentLocation
			                .setError(getString(R.string.empty_report_location));
			    }
		        }
		    }
	        });

	mIncidentDesc = (EditText) findViewById(R.id.incident_desc);
	mIncidentDesc.setOnFocusChangeListener(new View.OnFocusChangeListener()
	{

	    public void onFocusChange(View v, boolean hasFocus)
	    {
		if (!hasFocus)
		{
		    if (TextUtils.isEmpty(mIncidentDesc.getText()))
		    {
			mIncidentDesc
			        .setError(getString(R.string.empty_report_description));
		    }
		}
	    }

	});

	change_loc.setOnClickListener(new View.OnClickListener()
	{

	    @Override
	    public void onClick(View v)
	    {
		// TODO Auto-generated method stub
		Bundle flagBundle = new Bundle();
		flagBundle.putString("locationName", mIncidentLocation
		        .getText().toString());
		Intent intent = new Intent();
		intent.putExtras(flagBundle);
		intent.setClass(AddIncident.this, ChangeLoc.class);
		startActivityForResult(intent, REQUEST_CODE_CHANGE_LOC);
		setResult(RESULT_OK);
	    }
	});
	mBtnSend.setOnClickListener(new View.OnClickListener()
	{
	    public void onClick(View v)
	    {
		// Dipo Fix
		mError = false;
		if (TextUtils.isEmpty(mIncidentTitle.getText()))
		{
		    mErrorMessage = getString(R.string.empty_report_title);
		    mError = true;
		}

		if (TextUtils.isEmpty(mIncidentDesc.getText()))
		{
		    mErrorMessage += getString(R.string.empty_report_description);
		    mError = true;
		}

		/*if (TextUtils.isEmpty(mIncidentLocation.getText()))
		{
		    mErrorMessage += getString(R.string.empty_report_location);
		    mError = true;
		}
	*/
		 if(sLatitude == 0.0 && sLongitude == 0.0)
		//if(locDeterminedFlag==false)
		 {
			 if(currentLatitude == 0.0 && currentLongitude == 0.0)
			 //if(locDeterminedFlag==false)
			 {
				 mErrorMessage += getString(R.string.unable_to_locate_by_gps);
				    mError = true;
			 }
			 else
			 {
				 sLatitude = currentLatitude;
				 sLongitude = currentLongitude;
				 sLocationName = "Current Location";
				 Log.v("Oceanmaster", "####"+sLatitude + ", " + sLongitude);
			 }
		 }
		// Dipo Fix
		if (mVectorCategories.size() == 0)
		{
		    mErrorMessage += getString(R.string.empty_report_categories);
		    mError = true;
		}

		if (!mError)
		{
			AlertDialog.Builder builder = new AlertDialog.Builder(AddIncident.this);
			builder.setMessage("Are you sure to post it on line?")
			       .setCancelable(false)
			       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			   		    AddReportsTask addReportsTask = new AddReportsTask();
			   		    addReportsTask.appContext = AddIncident.this;
			   		    addReportsTask.execute();
			            //AddIncident.this.finish();
			           }
			       })
			       .setNegativeButton("No", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			                dialog.cancel();
			           }
			       });
			AlertDialog alert = builder.create();
			alert.show();

		}
		else
		{
		    final Toast t = Toast.makeText(AddIncident.this,
			    "Error!\n\n" + mErrorMessage, Toast.LENGTH_LONG);
		    t.show();
		    mErrorMessage = "";
		}

	    }
	});

	mBtnPicture.setOnClickListener(new View.OnClickListener()
	{
	    public void onClick(View v)
	    {
		if (!TextUtils.isEmpty(UshahidiPref.fileName))
		{
		    ImageManager.deleteImage(UshahidiPref.fileName);
		}
		showDialog(DIALOG_CHOOSE_IMAGE_METHOD);
	    }
	});

	mBtnCancel.setOnClickListener(new View.OnClickListener()
	{
	    public void onClick(View v)
	    {
		clearFields();
		// house keeping
		// ((LocationManager)getSystemService(Context.LOCATION_SERVICE))
		// .removeUpdates(new DeviceLocationListener());
		Intent intent = new Intent(AddIncident.this, Ushahidi.class);
		startActivityForResult(intent, GOTOHOME);
		setResult(RESULT_OK);
		finish();
	    }
	});

	mBtnAddCategory.setOnClickListener(new View.OnClickListener()
	{
	    public void onClick(View v)
	    {
		showDialog(DIALOG_MULTIPLE_CATEGORY);
		mCounter++;
	    }
	});

	/*
	 * mPickDate.setOnClickListener(new View.OnClickListener() {
	 * 
	 * public void onClick(View v) { showDialog(DATE_DIALOG_ID); } });
	 * 
	 * mPickTime.setOnClickListener(new View.OnClickListener() {
	 * 
	 * public void onClick(View v) { showDialog(TIME_DIALOG_ID); } });
	 */

	final Calendar c = Calendar.getInstance();
	mYear = c.get(Calendar.YEAR);
	mMonth = c.get(Calendar.MONTH);
	mDay = c.get(Calendar.DAY_OF_MONTH);
	mHour = c.get(Calendar.HOUR_OF_DAY);
	mMinute = c.get(Calendar.MINUTE);
	c.get(Calendar.AM_PM);
	updateDisplay();

    }

    // fetch categories
    public String[] showCategories()
    {
	Cursor cursor = UshahidiApplication.mDb.fetchIncidentCategories();

	// check if there are any existing categories in the database
	int categoryCount = cursor.getCount();
	int categoryAmount = 0;
	if (categoryCount > 0)
	{
	    categoryAmount = categoryCount;
	}
	else
	{
	    categoryAmount = 1;
	}

	String categories[] = new String[categoryAmount];

	int i = 0;
	if (cursor.moveToFirst())
	{

	    int titleIndex = cursor
		    .getColumnIndexOrThrow(UshahidiDatabase.CATEGORY_TITLE);

	    int idIndex = cursor
		    .getColumnIndexOrThrow(UshahidiDatabase.CATEGORY_ID);

	    do
	    {
		categories[i] = cursor.getString(titleIndex);
		mCategoriesTitle.put(String.valueOf(cursor.getInt(idIndex)),
		        cursor.getString(titleIndex));
		mCategoriesId.add(String.valueOf(cursor.getInt(idIndex)));
		i++;
	    }
	    while (cursor.moveToNext());
	}

	// sets category to be on the phone from the beginning if there aren't
	// any already
	if (mCategoriesId.isEmpty())
	{
	    categories[0] = UNCATEGORIZED_CATEGORY_TITLE;
	    mCategoriesId.add(UNCATEGORIZED_CATEGORY_ID);
	    mCategoriesTitle.put(UNCATEGORIZED_CATEGORY_ID,
		    UNCATEGORIZED_CATEGORY_TITLE);
	}

	cursor.close();
	return categories;

    }

    // reset records in the field
    private void clearFields()
    {
	mBtnPicture = (Button) findViewById(R.id.btnPicture);
	mBtnAddCategory = (Button) findViewById(R.id.add_category);
	mIncidentTitle.setText("");
	mIncidentLocation.setText("");
	mIncidentDesc.setText("");
	mVectorCategories.clear();
	mSelectedCategories.setText("");
	mSelectedPhoto.setImageDrawable(null);
	mSelectedPhoto.setImageBitmap(null);
	mCounter = 0;
	updateDisplay();

	// clear persistent data
	SharedPreferences.Editor editor = getPreferences(0).edit();
	editor.putString("title", "");
	editor.putString("desc", "");
	editor.putString("date", "");
	editor.putString("cate", "");
	editor.commit();

    }
    
    public Bitmap getThumbnail(Uri uri) throws FileNotFoundException, IOException{
        InputStream input = this.getContentResolver().openInputStream(uri);

        BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
        onlyBoundsOptions.inJustDecodeBounds = true;
        onlyBoundsOptions.inDither=true;//optional
        onlyBoundsOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//optional
        BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
        input.close();
        if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1))
            return null;

        int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth;

        double ratio = (originalSize > THUMBNAIL_SIZE) ? (originalSize / THUMBNAIL_SIZE) : 1.0;

        BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
        bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio);
        bitmapOptions.inDither=true;//optional
        bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//optional
        input = this.getContentResolver().openInputStream(uri);
        Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
        input.close();
        return bitmap;
    }
    
    private static int getPowerOfTwoForSampleRatio(double ratio){
        int k = Integer.highestOneBit((int)Math.floor(ratio));
        if(k==0) return 1;
        else return k;
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
	super.onActivityResult(requestCode, resultCode, data);
	// The preferences returned if the request code is what we had given
	// earlier in startSubActivity
	switch (requestCode)
	{

	    case REQUEST_CODE_CAMERA:
		if (resultCode != RESULT_OK)
		{
		    return;
		}

		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
		mBundle = null;
		mExtras = data.getExtras();
		if (mExtras != null)
		    mBundle = mExtras.getBundle("filename");

		if (mBundle != null && !mBundle.isEmpty())
		{
			
		    UshahidiPref.fileName = mBundle.getString("name");
		    
		    Bitmap b_c=ImageManager.getBitmap(UshahidiPref.fileName);
			ByteArrayOutputStream byteArrayos_c = new ByteArrayOutputStream();

			try
			{
			    b_c.compress(CompressFormat.JPEG, 75, byteArrayos_c);
			    byteArrayos_c.flush();
			}
			catch (OutOfMemoryError e)
			{

			    break;
			}
			catch (IOException e)
			{

			    break;
			}

		    mFilename = "android_pic_upload" + randomString() + ".jpg";
			ImageManager.writeImage(byteArrayos_c.toByteArray(), mFilename);
			UshahidiPref.fileName = mFilename;
			
		    mSelectedPhoto.setImageBitmap(ImageManager
			    .getBitmap(UshahidiPref.fileName));
		    mSelectedPhoto
			    .setScaleType(ImageView.ScaleType.CENTER_CROP);
		}
		break;

	    case REQUEST_CODE_IMAGE:

		if (resultCode != RESULT_OK)
		{
		    return;
		}

		Uri uri = data.getData();
		Bitmap b = null;

		try
		{
		    // Changed by Oceanmaster, Using a new function to save
		    // memory
		    
		    //b =MediaStore.Images.Media.getBitmap(this.getContentResolver(),uri);
		    b= this.getThumbnail(uri);
		    //File file = new File(uri.getEncodedPath());
		    //b = decodeFile(file);
		}
		catch (FileNotFoundException e)
		{
		    Util.showToast(AddIncident.this,
			    "Error : Picture doesn't exist");// Oceanmaster:tell
							     // something
		    break;
		}
		catch (IOException e)
		{
		    Util.showToast(AddIncident.this,
			    "Error : Something wrong while fetching data from Gallery");// Oceanmaster:tell
											// something
		    break;
		}

		ByteArrayOutputStream byteArrayos = new ByteArrayOutputStream();

		try
		{
		    b.compress(CompressFormat.JPEG, 75, byteArrayos);
		    byteArrayos.flush();
		}
		catch (OutOfMemoryError e)
		{

		    break;
		}
		catch (IOException e)
		{

		    break;
		}

		mFilename = "android_pic_upload" + randomString() + ".jpg";
		ImageManager.writeImage(byteArrayos.toByteArray(), mFilename);
		UshahidiPref.fileName = mFilename;

		mSelectedPhoto.setImageBitmap(ImageManager
		        .getBitmap(UshahidiPref.fileName));
		mSelectedPhoto.setScaleType(ImageView.ScaleType.CENTER_CROP);
		break;

	    case VIEW_MAP:
		if (resultCode != RESULT_OK)
		{
		    return;
		}

		mBundle = null;
		mExtras = data.getExtras();
		if (mExtras != null)
		    mBundle = mExtras.getBundle("locations");

		if (mBundle != null && !mBundle.isEmpty())
		{
		    mIncidentLocation.setText(mBundle.getString("location"));

		    AddIncident.sLatitude = mBundle.getDouble("latitude");
		    AddIncident.sLongitude = mBundle.getDouble("longitude");
		}
		break;

	    case REQUEST_CODE_CHANGE_LOC:
	    	if(resultCode==RESULT_OK){
	    		Bundle bundleForChangedLocation = new Bundle();
	    		bundleForChangedLocation = data.getExtras();
	    		if(bundleForChangedLocation != null){
	    	
	    		
	    			String locationName = String.valueOf(bundleForChangedLocation.get("locationName"));
	    			if(locationName!=null)
	    			{
	    				sLatitude = Double.valueOf(bundleForChangedLocation.getString("Latitude"));
	    				sLongitude = Double.valueOf(bundleForChangedLocation.getString("Longitude"));
	    				sLocationName = locationName.substring(0);
	    				//placeMarker((int)(sLatitude*1000000), (int)(sLongitude*1000000));
	    			//centerLocation(getPoint(sLatitude, sLongitude),false);
	    			//mReportLocation.setText(String.valueOf(sLatitude) + ", "
	    				//	+ String.valueOf(sLongitude));
	    				mIncidentLocation.setText(sLocationName);
	    			}
	    			else
	    			{
	    				sLatitude = 0.0;
	    				sLongitude = 0.0;
	    				sLocationName = "";
	    			}
	    		}
	    		Log.v("Oceanmaster",
	   	             "received location is:"+sLocationName+ "(" +sLatitude +", "+ sLongitude+")");
	    	}
	    	break;
	}
    }

    private static Random random = new Random();

    protected static String randomString()
    {
	return Long.toString(random.nextLong(), 10);
    }

    //
    final Runnable mSentIncidentOffline        = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       if (addToDb() == -1)
		                                       {
		                                           mHandler.post(mSentIncidentFail);
		                                       }
		                                       else
		                                       {
		                                           mHandler.post(mSentIncidentOfflineSuccess);
		                                           // clearFields();
		                                       }
	                                           }
	                                       };

    final Runnable mSentIncidentFail           = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       Util.showToast(
		                                               AddIncident.this,
		                                               R.string.failed_to_add_report_online);
	                                           }
	                                       };

    final Runnable mSentIncidentOfflineFail    = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       Util.showToast(
		                                               AddIncident.this,
		                                               R.string.failed_to_add_report_offline);
	                                           }
	                                       };

    final Runnable mSentIncidentOfflineSuccess = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       Util.showToast(
		                                               AddIncident.this,
		                                               R.string.report_successfully_added_offline);

	                                           }
	                                       };

    //
    final Runnable mSendIncidentOnline         = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       if (!postToOnline())
		                                       {
		                                           mHandler.post(mSentIncidentFail);
		                                       }
		                                       else
		                                       {
		                                           mHandler.post(mSentIncidentSuccess);

		                                       }
	                                           }
	                                       };

    //
    final Runnable mSentIncidentSuccess        = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       Util.showToast(
		                                               AddIncident.this,
		                                               R.string.report_successfully_added_online);

	                                           }
	                                       };

    /**
     * Create various dialog
     */
    @Override
    protected Dialog onCreateDialog(int id)
    {
	switch (id)
	{
	    case DIALOG_ERROR_NETWORK:
	    {
		AlertDialog dialog = (new AlertDialog.Builder(this)).create();
		dialog.setTitle(getString(R.string.network_error));
		dialog.setMessage(getString(R.string.network_error_msg));
		dialog.setButton2(getString(R.string.btn_ok),
		        new Dialog.OnClickListener()
		        {
			    public void onClick(DialogInterface dialog,
			            int which)
			    {
			        dialog.dismiss();
			    }
		        });
		dialog.setCancelable(false);
		return dialog;
	    }
	    case DIALOG_ERROR_SAVING:
	    {
		AlertDialog dialog = (new AlertDialog.Builder(this)).create();
		dialog.setTitle(getString(R.string.network_error));
		dialog.setMessage(getString(R.string.file_system_error_msg));
		dialog.setButton2(getString(R.string.btn_ok),
		        new Dialog.OnClickListener()
		        {
			    public void onClick(DialogInterface dialog,
			            int which)
			    {
			        dialog.dismiss();
			    }
		        });
		dialog.setCancelable(false);
		return dialog;
	    }

	    case DIALOG_CHOOSE_IMAGE_METHOD:
	    {
		AlertDialog dialog = (new AlertDialog.Builder(this)).create();
		dialog.setTitle(getString(R.string.choose_method));
		dialog.setMessage(getString(R.string.how_to_select_pic));
		dialog.setButton(getString(R.string.gallery_option),
		        new Dialog.OnClickListener()
		        {
			    // TODO
			    public void onClick(DialogInterface dialog,
			            int which)
			    {
			        Intent intent = new Intent();
			        intent.setAction(Intent.ACTION_PICK);
			        intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
			        Log.v("Oceanmaster",
			                "Gallery Image Path Selected");
			        startActivityForResult(intent,
			                REQUEST_CODE_IMAGE);
			        dialog.dismiss();
			    }
		        });
		dialog.setButton2(getString(R.string.btn_cancel),
		        new Dialog.OnClickListener()
		        {
			    public void onClick(DialogInterface dialog,
			            int which)
			    {
			        dialog.dismiss();
			    }
		        });

		dialog.setButton3(getString(R.string.camera_option),
		        new Dialog.OnClickListener()
		        {
			    public void onClick(DialogInterface dialog,
			            int which)
			    {

			        Intent launchPreferencesIntent = new Intent()
			                .setClass(AddIncident.this,
			                        ImageCapture.class);

			        // Make it a subactivity so we know when it
				// returns
			        startActivityForResult(launchPreferencesIntent,
			                REQUEST_CODE_CAMERA);
			        dialog.dismiss();

			    }
		        });

		dialog.setCancelable(false);
		return dialog;

	    }

	    case DIALOG_MULTIPLE_CATEGORY:
	    {
		return new AlertDialog.Builder(this)
		        .setTitle(R.string.add_categories)
		        .setMultiChoiceItems(
		                showCategories(),
		                null,
		                new DialogInterface.OnMultiChoiceClickListener()
		                {
			            public void onClick(DialogInterface dialog,
			                    int whichButton, boolean isChecked)
			            {

			                if (isChecked)
			                {
				            mVectorCategories.add(mCategoriesId
				                    .get(whichButton));
				            // put together
				            // if (!mVectorCategories.isEmpty())
				            // {
				            // mSelectedCategories.setText(
				            // Util.limitString(
				            // //
				            // mCategoriesTitle.get(mVectorCategories.get(0)),
				            // Util.implode(getCategoriesByIds(mVectorCategories)),
				            // 15));
				            // }

				            mError = false;
			                }
			                else
			                {
				            // fixed a crash here.
				            mVectorCategories
				                    .remove(mCategoriesId
				                            .get(whichButton));
				            // put down together
				            // if (mVectorCategories.isEmpty())
				            // {
				            // mSelectedCategories.setText("");
				            // }
				            // else
				            // {
				            // mSelectedCategories.setText(
				            // Util.limitString(
				            // //mCategoriesTitle.get(mVectorCategories.get(0)),
				            // Util.implode(getCategoriesByIds(mVectorCategories)),
				            // 15));
				            // }
			                }

			            }
		                })
		        .setPositiveButton(R.string.btn_ok,
		                new DialogInterface.OnClickListener()
		                {
			            public void onClick(DialogInterface dialog,
			                    int whichButton)
			            {

			                /* User clicked Yes so do some stuff */
			                if (mVectorCategories.isEmpty())
			                {
				            mSelectedCategories.setText("");
			                }
			                else
			                {
				            mSelectedCategories.setText(Util.limitString(
				                    // mCategoriesTitle.get(mVectorCategories.get(0)),
				                    Util.implode(getCategoriesByIds(mVectorCategories)),
				                    15));
			                }
			            }
		                }).create();
	    }

	    case TIME_DIALOG_ID:
		return new TimePickerDialog(this, mTimeSetListener, mHour,
		        mMinute, false);

	    case DATE_DIALOG_ID:
		return new DatePickerDialog(this, mDateSetListener, mYear,
		        mMonth, mDay);
	}
	return null;
    }

    @Override
    protected void onPrepareDialog(int id, Dialog dialog)
    {
	switch (id)
	{
	    case TIME_DIALOG_ID:
		((TimePickerDialog) dialog).updateTime(mHour, mMinute);
		break;
	    case DATE_DIALOG_ID:
		((DatePickerDialog) dialog).updateDate(mYear, mMonth, mDay);
		break;
	}
    }

    private void updateDisplay()
    {
	String amPm;
	mTimeDigits = new HashMap<Integer, Integer>();

	mTimeDigits.put(00, 12);
	mTimeDigits.put(13, 1);
	mTimeDigits.put(14, 2);
	mTimeDigits.put(15, 3);
	mTimeDigits.put(16, 4);
	mTimeDigits.put(17, 5);
	mTimeDigits.put(18, 6);
	mTimeDigits.put(19, 7);
	mTimeDigits.put(20, 8);
	mTimeDigits.put(21, 9);
	mTimeDigits.put(22, 10);
	mTimeDigits.put(23, 11);
	mTimeDigits.put(24, 12);
	mTimeDigits.put(12, 12);
	mTimeDigits.put(1, 1);
	mTimeDigits.put(2, 2);
	mTimeDigits.put(3, 3);
	mTimeDigits.put(4, 4);
	mTimeDigits.put(5, 5);
	mTimeDigits.put(6, 6);
	mTimeDigits.put(7, 7);
	mTimeDigits.put(8, 8);
	mTimeDigits.put(9, 9);
	mTimeDigits.put(10, 10);
	mTimeDigits.put(11, 11);
	mTimeDigits.put(12, 12);
	if (mHour >= 12)
	    amPm = "PM";
	else
	    amPm = "AM";

	String strDate = new StringBuilder()

	        // Month is 0 based so add 1
	        .append(mYear).append("-").append(pad(mMonth + 1)).append("-")
	        .append(pad(mDay)).toString();

	String dateTime = Util.formatDate("yyyy-MM-dd", strDate,
	        "MMMM dd, yyyy");

	// mIncidentDate.setText(dateTime + " at " + pad(mTimeDigits.get(mHour))
	// + ":" + pad(mMinute)
	// + " " + amPm);

	mDateToSubmit = new StringBuilder()
	        // Month is 0 based so add 1
	        .append(pad(mMonth + 1)).append("/").append(pad(mDay))
	        .append("/").append(mYear).append(" ")
	        .append(pad(mTimeDigits.get(mHour))).append(":")
	        .append(pad(mMinute)).append(" ").append(amPm).toString();
    }

    private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener()
	                                                        {

	                                                            public void onDateSet(
	                                                                    DatePicker view,
	                                                                    int year,
	                                                                    int monthOfYear,
	                                                                    int dayOfMonth)
	                                                            {
		                                                        mYear = year;
		                                                        mMonth = monthOfYear;
		                                                        mDay = dayOfMonth;
		                                                        updateDisplay();
	                                                            }
	                                                        };

    private TimePickerDialog.OnTimeSetListener mTimeSetListener = new TimePickerDialog.OnTimeSetListener()
	                                                        {

	                                                            public void onTimeSet(
	                                                                    TimePicker view,
	                                                                    int hourOfDay,
	                                                                    int minute)
	                                                            {
		                                                        mHour = hourOfDay;
		                                                        mMinute = minute;

		                                                        updateDisplay();
	                                                            }
	                                                        };

    private static String pad(int c)
    {
	if (c >= 10)
	    return String.valueOf(c);
	else
	    return "0" + String.valueOf(c);
    }

    /**
     * Insert incident data into db when app is offline.
     * 
     * @author henryaddo
     */
    public long addToDb()
    {

	String dates[] = mDateToSubmit.split(" ");
	String time[] = dates[1].split(":");

	List<AddIncidentData> addIncidentsData = new ArrayList<AddIncidentData>();
	AddIncidentData addIncidentData = new AddIncidentData();
	addIncidentsData.add(addIncidentData);

	addIncidentData.setIncidentTitle(mIncidentTitle.getText().toString());
	addIncidentData.setIncidentDesc(mIncidentDesc.getText().toString());
	addIncidentData.setIncidentDate(dates[0]);
	addIncidentData.setIncidentHour(Integer.parseInt(time[0]));
	addIncidentData.setIncidentMinute(Integer.parseInt(time[1]));
	addIncidentData.setIncidentAmPm(dates[2].toLowerCase());
	addIncidentData.setIncidentCategories(Util.implode(mVectorCategories));
	addIncidentData.setIncidentLocName(sLocationName);
	addIncidentData.setIncidentLocLatitude(String.valueOf(sLatitude));
	addIncidentData.setIncidentLocLongitude(String.valueOf(sLongitude));
	addIncidentData.setIncidentPhoto(UshahidiPref.fileName);
	addIncidentData.setPersonFirst(UshahidiPref.firstname);
	addIncidentData.setPersonLast(UshahidiPref.lastname);
	addIncidentData.setPersonEmail(UshahidiPref.email);

	// add it to database.
	return UshahidiApplication.mDb.addIncidents(addIncidentsData);

    }
    private void updateRefreshStatus()
    {
	findViewById(R.id.refresh_report_btn).setVisibility(
	        refreshState ? View.GONE : View.VISIBLE);
	findViewById(R.id.title_refresh_progress).setVisibility(
	        refreshState ? View.VISIBLE : View.GONE);
    }
    /**
     * Post directly to online.
     * 
     * @author henryaddo
     */
    public boolean postToOnline()
    {

	if (TextUtils.isEmpty(UshahidiPref.domain)
	        || UshahidiPref.domain.equalsIgnoreCase("http://"))
	{
	    return false;
	}

	String dates[] = mDateToSubmit.split(" ");
	String time[] = dates[1].split(":");
	String categories = Util.implode(mVectorCategories);

	StringBuilder urlBuilder = new StringBuilder(UshahidiPref.domain);
	urlBuilder.append("/api");

	mParams.put("task", "report");
	mParams.put("incident_title", mIncidentTitle.getText().toString());
	mParams.put("incident_description", mIncidentDesc.getText().toString());
	mParams.put("incident_date", dates[0]);
	mParams.put("incident_hour", time[0]);
	mParams.put("incident_minute", time[1]);
	mParams.put("incident_ampm", dates[2].toLowerCase());
	mParams.put("incident_category", categories);
	mParams.put("latitude", String.valueOf(sLatitude));
	mParams.put("longitude", String.valueOf(sLongitude));
	mParams.put("location_name", sLocationName);
	mParams.put("person_first", UshahidiPref.firstname);
	mParams.put("person_last", UshahidiPref.lastname);
	mParams.put("person_email", UshahidiPref.email);
	mParams.put("filename", UshahidiPref.fileName);

	try
	{
	    return UshahidiHttpClient.PostFileUpload(urlBuilder.toString(),
		    mParams);
	}
	catch (IOException e)
	{
		//System.out.println(e.toString());
	    e.printStackTrace();
	    return false;
	}

    }

    /**
     * Upon being resumed we can retrieve the current state. This allows us to
     * update the state if it was changed at any time while paused.
     */
   

    public void onClickHome(View v)
    {
	goHome(this);
    }

    /**
     * Go back to the home activity.
     * 
     * @param context
     *            Context
     * @return void
     */

    public void goHome(Context context)
    {
	final Intent intent = new Intent(context, Ushahidi.class);
	intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
	context.startActivity(intent);
    }

    public void onSearchDeployments(View v)
    {
	Intent intent = new Intent(AddIncident.this, DeploymentSearch.class);
	startActivityForResult(intent, VIEW_SEARCH);
	setResult(RESULT_OK);
    }

    /**
     * Any time we are paused we need to save away the current state, so it will
     * be restored correctly when we are resumed.
     */
   

    /**
     * get the real location name from the latitude and longitude.
     */
   
    /**
     * Sets nVectorCategories
     * 
     * @param aVectorCategories
     */
    public void setVectorCategories(Vector<String> aVectorCategories)
    {
	mVectorCategories = aVectorCategories;
    }

    // thread class
    private class AddReportsTask extends AsyncTask<Void, Void, Integer>
    {

	protected Integer status;
	private ProgressDialog dialog;
	protected Context appContext;
	// thread for displaying the SplashScreen


	@Override
	protected void onPreExecute()
	{
	    refreshState = true;
	    updateRefreshStatus();
	    this.dialog = ProgressDialog.show(appContext,
		    getString(R.string.please_wait),
		    getString(R.string.posting_new_reports), true);
		// thread for displaying the SplashScreen
		Thread progressBarTread = new Thread()
		{
		    @Override
		    public void run()
		    {
			try
			{
				sleep(1000);
			}
			catch (InterruptedException e)
			{
			    // do nothing
			}
		    }
		};
		progressBarTread.start();
	    //setProgressBarIndeterminateVisibility(true);

	}

	@Override
	protected Integer doInBackground(Void... mParams)
	{
	    if (Util.isConnected(AddIncident.this))
	    {
			if (!postToOnline())
			{
			    addToDb();
			    status = 1; // fail
			}
			else
			{
			    status = 0; // success
			}
	    }
	    else
	    {
			addToDb();
			status = 2; // no internet connection
	    }
	    return status;
	}

	@Override
	protected void onPostExecute(Integer result)
	{
		/////////////////////////dismissing the progress bar
	    this.dialog.cancel();
	    refreshState = false;
	    updateRefreshStatus();
	    ////////////////////////
	    if (result == 2)
	    {
		clearFields();
		Util.showToast(appContext,
		        R.string.report_successfully_added_offline);
		
		// -----------------------------------
		// need to test the time needed to keep the device asleep
		// to make it jump to main page smoothly
		// --------------------------------
		goHome(appContext);
	    }
	    else if (result == 1)
	    {
		clearFields();
		Util.showToast(appContext, R.string.failed_to_add_report_online);
	    }
	    else if (result == 0)
	    {
		clearFields();
		// after a successful upload, delete the file
		File f = new File(UshahidiPref.savePath + UshahidiPref.fileName);
		if (f.exists())
		{
		    f.delete();
		}

	    
		Util.showToast(appContext,
		        R.string.report_successfully_added_online);
		// -----------------------------------
		// need to test the time needed to keep the device asleep
		// to make it jump to main page smoothly
		// --------------------------------
		goHome(appContext);
	    }
	    setProgressBarIndeterminateVisibility(false);
	}
    }

    /*
     * private void placeMarker(int markerLatitude, int markerLongitude) {
     * 
     * Drawable marker = getResources().getDrawable(R.drawable.marker);
     * 
     * marker.setBounds(0, 0, marker.getIntrinsicWidth(),
     * marker.getIntrinsicHeight()); mapView.getController().setZoom(14);
     * 
     * mapView.setBuiltInZoomControls(true); mapView.getOverlays().add(new
     * MapMarker(marker, markerLatitude, markerLongitude)); }
     * 
     * // Location stuff public GeoPoint getPoint(double lat, double lon) {
     * return (new GeoPoint((int)(lat * 1000000.0), (int)(lon * 1000000.0))); }
     * 
     * private void centerLocation(GeoPoint centerGeoPoint) {
     * 
     * mapController.animateTo(centerGeoPoint);
     * 
     * // initilaize latitude and longitude for them to be passed to the //
     * AddIncident Activity. sLatitude = centerGeoPoint.getLatitudeE6() / 1.0E6;
     * sLongitude = centerGeoPoint.getLongitudeE6() / 1.0E6;
     * mIncidentLocation.setText(getLocationFromLatLon(sLatitude, sLongitude));
     * placeMarker(centerGeoPoint.getLatitudeE6(),
     * centerGeoPoint.getLongitudeE6());
     * 
     * }
     * 
     * private class MapMarker extends ItemizedOverlay<OverlayItem> {
     * 
     * private List<OverlayItem> locations = new ArrayList<OverlayItem>();
     * 
     * private Drawable marker;
     * 
     * private OverlayItem myOverlayItem;
     * 
     * public MapMarker(Drawable defaultMarker, int LatitudeE6, int LongitudeE6)
     * { super(defaultMarker); this.marker = defaultMarker;
     * 
     * // create locations of interest GeoPoint myPlace = new
     * GeoPoint(LatitudeE6, LongitudeE6);
     * 
     * myOverlayItem = new OverlayItem(myPlace, " ", " ");
     * 
     * locations.add(myOverlayItem);
     * 
     * populate();
     * 
     * }
     * 
     * @Override protected OverlayItem createItem(int i) { return
     * locations.get(i); }
     * 
     * @Override public int size() { return locations.size(); }
     * 
     * @Override public void draw(Canvas canvas, MapView mapView, boolean
     * shadow) { super.draw(canvas, mapView, shadow); boundCenterBottom(marker);
     * }
     * 
     * }
     * 
     * // Fetches the current location of the device. private void
     * setDeviceLocation() {
     * 
     * DeviceLocationListener listener = new DeviceLocationListener();
     * LocationManager manager =
     * (LocationManager)getSystemService(Context.LOCATION_SERVICE);
     * 
     * long updateTimeMsec = 1000L;
     * 
     * // get low accuracy provider LocationProvider low =
     * manager.getProvider(manager.getBestProvider( Util.createCoarseCriteria(),
     * true));
     * 
     * // get high accuracy provider LocationProvider high =
     * manager.getProvider(manager.getBestProvider( Util.createFineCriteria(),
     * true));
     * 
     * manager.requestLocationUpdates(low.getName(), updateTimeMsec, 500.0f,
     * listener);
     * 
     * manager.requestLocationUpdates(high.getName(), updateTimeMsec, 500.0f,
     * listener);
     * 
     * }
     * 
     * // get the current location of the device/user public class
     * DeviceLocationListener implements LocationListener { public void
     * onLocationChanged(Location location) {
     * 
     * if (location != null) {
     * ((LocationManager)getSystemService(Context.LOCATION_SERVICE))
     * .removeUpdates(DeviceLocationListener.this);
     * 
     * sLatitude = location.getLatitude(); sLongitude = location.getLongitude();
     * 
     * centerLocation(getPoint(sLatitude, sLongitude));
     * mReportLocation.setText(String.valueOf(sLatitude) + ", " +
     * String.valueOf(sLongitude)); } }
     * 
     * public void onProviderDisabled(String provider) {
     * Util.showToast(AddIncident.this, R.string.location_not_found); }
     * 
     * public void onProviderEnabled(String provider) {
     * 
     * }
     * 
     * public void onStatusChanged(String provider, int status, Bundle extras) {
     * 
     * } }
     * 
     * @Override protected boolean isRouteDisplayed() { return false; }
     */
    private Vector<String> getCategoriesByIds(Vector<String> ids)
    {
	Vector<String> cates = new Vector<String>();
	for (String id : ids)
	{
	    if (mCategoriesTitle.containsKey(id))
		cates.add(mCategoriesTitle.get(id));
	}
	return cates;
    }

    // Added by Oceanmaster
    // Used to decode file , trying to use as little memory as possible
    private Bitmap decodeFile(File f) throws FileNotFoundException
    {
	// Decode image size
	BitmapFactory.Options o = new BitmapFactory.Options();
	o.inJustDecodeBounds = true;
	BitmapFactory.decodeStream(new FileInputStream(f), null, o);
	// The new size we want to scale to
	final int REQUIRED_SIZE = 70;
	// Find the correct scale value. It should be the power of 2.
	int width_tmp = o.outWidth, height_tmp = o.outHeight;
	int scale = 1;
	while (true)
	{
	    if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
		break;
	    width_tmp /= 2;
	    height_tmp /= 2;
	    scale *= 2;
	}
	// Decode with inSampleSize
	BitmapFactory.Options o2 = new BitmapFactory.Options();
	o2.inSampleSize = scale;
	return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    }

}
